#!/bin/bash
 #=================== SYSTEM ===================#
  SYSTEMD="/etc/systemd/system"
  INITD="/etc/init.d"
  ETCDEF="/etc/default"
  DATABK="/home/print3D/printer_data"
  #清华
  PIP3YUAN="https://pypi.tuna.tsinghua.edu.cn/simple/"
  #阿里
  #PIP3YUAN="http://mirrors.aliyun.com/pypi/simple/"
  #中国科技大学
  #PIP3YUAN="https://pypi.mirrors.ustc.edu.cn/simple/"
  #华中科技大学
  #PIP3YUAN="http://pypi.hustunique.com/simple/"
  #上海交通大学
  #PIP3YUAN="https://mirror.sjtu.edu.cn/pypi/web/simple/"
  #豆瓣
  #PIP3YUAN="http://pypi.douban.com/simple/"
  #百度
  #PIP3YUAN="https://mirror.baidu.com/pypi/simple"
  #搜狐
  #PIP3YUAN="http://mirrors.sohu.com/Python/"
  #=================== KIAUH ==================#
### sourcing all additional scripts
  KIAUH_SRCDIR="/home/print3D/kiauh"
  KIAUH_REPO="https://gitee.com/miroky/kiauh.git"
  green=$(echo -en "\e[92m")
  yellow=$(echo -en "\e[93m")
  magenta=$(echo -en "\e[35m")
  red=$(echo -en "\e[91m")
  cyan=$(echo -en "\e[96m")
  white=$(echo -en "\e[39m")
  home1="/home/print3D"
  INI_FILE="/home/print3D/kiauh.ini"
  LOGFILE="/tmp/kiauh.log"
  RESOURCES="${KIAUH_SRCDIR}/resources"
  BACKUP_DIR="/home/print3D/kiauh-backups"
  #=====================PIP======================#
  # for using official pip source, comment next line
  PIP_MIRROR="https://pypi.tuna.tsinghua.edu.cn/simple"
 
  #================= MAINSAIL ===================#
  MAINSAIL_DIR="/home/print3D/mainsail"
  MAINSAIL_REPO_API="https://gitee.com/Neko-vecter/mainsail-releases/raw/main/mainsail-res"
  MAINSAIL_TAGS="https://gitee.com/Neko-vecter/mainsail-releases/raw/main/Neko-mainsail-res"
  MAINSAIL_MACRO="https://gitee.com/Neko-vecter/mainsail-releases/raw/main/klipper_config/mainsail.cfg"
  #================== FLUIDD ====================#
  FLUIDD_DIR="/home/print3D/fluidd"
  FLUIDD_REPO_API="https://gitee.com/Neko-vecter/fluidd-releases/raw/main/fluidd-res"
  FLUIDD_TAGS="https://gitee.com/Neko-vecter/fluidd-releases/raw/main/Neko-fluidd-res"
  FLUIDD_MACRO="https://gitee.com/Neko-vecter/fluidd-releases/raw/main/klipper_config/fluidd.cfg"
  NGINX_SA="/etc/nginx/sites-available"
  NGINX_SE="/etc/nginx/sites-enabled"
  NGINX_CONFD="/etc/nginx/conf.d"
  
Red='\033[0;31m'
Green='\033[0;32m'
Cyan='\033[0;36m'
Normal='\033[0m'

#===================================================#
#================== INSTALL FLUIDD =================#
#===================================================#
function install_fluidd() {

   ### 检查依赖项
  local dep=(wget nginx)
  dependency_check "${dep[@]}"
  ### 检测冲突的Haproxy和Apache2安装
  status_msg "正在初始化Fluidd安装 ..."
  mkdir -p /etc/nginx/conf.d
  mkdir -p /etc/nginx/sites-available
  mkdir -p /etc/nginx/sites-enabled
  sed -i 's/user www-data;/\#user www-data;/' /etc/nginx/nginx.conf
  sed -i '/\/etc\/nginx\/http.d\/\*.conf;/a\        include \/etc\/nginx\/sites-enabled\/\*;'  /etc/nginx/nginx.conf
  sed -i "/http {/a\map \$http_upgrade \$connection_upgrade {\n    default upgrade;\n    ''      close;\n   }"  /etc/nginx/nginx.conf
  sed -i 's/http.d/conf.d/g' /etc/nginx/nginx.conf
  ### 下载fluidd
  download_fluidd
  ### 创造 /etc/nginx/conf.d/upstreams.conf
  set_upstream_nginx_cfg
  ### 创造 /etc/nginx/sites-available/<interface config>
  set_nginx_cfg "fluidd"
  ### ubuntu 21及以上版本上的nginx需要特殊权限才能访问这些文件
  set_nginx_permissions
  ### 符号链接nginx日志
  symlink_webui_nginx_log "fluidd"
  ### 要求用户安装推荐的Web界面宏
  download_fluidd_macros
  ### 确认消息
  print_confirm "Fluidd已设置!"
}
function download_fluidd() {
  local url
  url=$(get_fluidd_download_url)

  status_msg "正在${url}从下载Fluidd  ..."

  if [[ -d ${FLUIDD_DIR} ]]; then
    rm -rf "${FLUIDD_DIR}"
  fi

  mkdir "${FLUIDD_DIR}" && cd "${FLUIDD_DIR}"

  if wget "${url}"; then
    ok_msg "下载完成!"
    status_msg "正在提取存档 ..."
    unzip -q -o ./*.zip && ok_msg "Done!"
    status_msg "删除下载的存档 ..."
    rm -rf ./*.zip && ok_msg "Done!"
  else
    print_error "下载 Fluidd from\n ${url}\n failed!"
    
  fi
}
function get_fluidd_download_url() {
  local tags latest_tag latest_url stable_tag stable_url url
  tags=$(curl -s "${FLUIDD_TAGS}" | grep "name" | cut -d'"' -f4)
  download_url=$(curl -s "${FLUIDD_TAGS}" | grep "download_url" | cut -d'"' -f4)
  # 获取最新标签和url
  latest_tag=$(echo "${tags}" | head -1)
  latest_url=$(echo "${download_url}" | head -1)
  url="${latest_url}"
  echo "${url}"
}
function set_upstream_nginx_cfg() {
  local upstreams="${NGINX_CONFD}/upstreams.conf"
  local common_vars="${NGINX_CONFD}/common_vars.conf"
  ### 将nginx配置复制到目标目标
  [[ ! -f ${upstreams} ]] &&  cp "${RESOURCES}/upstreams.conf" "${upstreams}"
  [[ ! -f ${common_vars} ]] &&  cp "${RESOURCES}/common_vars.conf" "${common_vars}"
}
function set_nginx_cfg() {
  local interface=${1}
    #检查相关性
    local cfg_src="${RESOURCES}/${interface}"
    local cfg_dest="/etc/nginx/sites-available/${interface}"
    status_msg "正在为创建NGINX配置 ${interface^} ..."
    # 将配置复制到目标并设置正确的用户名
    [[ -f ${cfg_dest} ]] &&  rm -rf "${cfg_dest}"
    cp "${cfg_src}" "${cfg_dest}"
    sed -i "/root/s/pi/print3D/" "${cfg_dest}"
    if [[ ${interface} == "fluidd" ]]; then
       sed -i "s/listen\s[0-9]*;/listen 8080;/" "${cfg_dest}"
       sed -i "s/listen\s\[\:*\]\:[0-9]*;/listen \[::\]\:8080;/" "${cfg_dest}"
       sed -i 's/http:\/\/apiserver/http:\/\/127.0.0.1:7125/g' "${cfg_dest}"
       sed -i 's/mjpgstreamer1/127.0.0.1:8080/g' "${cfg_dest}"
       sed -i 's/mjpgstreamer2/127.0.0.1:8081/g' "${cfg_dest}"
       sed -i 's/mjpgstreamer3/127.0.0.1:8082/g' "${cfg_dest}"
       sed -i 's/mjpgstreamer4/127.0.0.1:8083/g' "${cfg_dest}"
       ok_msg "${interface^} 为端口配置 8080!"
    else
       sed -i "s/listen\s[0-9]*;/listen 8081;/" "${cfg_dest}"
       sed -i "s/listen\s\[\:*\]\:[0-9]*;/listen \[::\]\:8081;/" "${cfg_dest}"
       sed -i 's/http:\/\/apiserver/http:\/\/127.0.0.1:7125/g' "${cfg_dest}"
       sed -i 's/mjpgstreamer1/127.0.0.1:8080/g' "${cfg_dest}"
       sed -i 's/mjpgstreamer2/127.0.0.1:8081/g' "${cfg_dest}"
       sed -i 's/mjpgstreamer3/127.0.0.1:8082/g' "${cfg_dest}"
       sed -i 's/mjpgstreamer4/127.0.0.1:8083/g' "${cfg_dest}"
       ok_msg "${interface^} 为端口配置 8081!"
    fi
    #删除nginx默认配置
    if [[ -e "/etc/nginx/sites-enabled/default" ]]; then
      rm "/etc/nginx/sites-enabled/default"
    fi

    #为自己的站点创建符号链接
    if [[ ! -e "/etc/nginx/sites-enabled/${interface}" ]]; then
       ln -s "/etc/nginx/sites-available/${interface}" "/etc/nginx/sites-enabled/"
    fi
    ok_msg "NGINX 的配置 ${interface^} 已设置!"

}
function set_nginx_permissions() {
  local homedir_perm
  local exec_perms_count
  homedir_perm=$(ls -ld "${home}/home/print3D")
  exec_perms_count=$(echo "${homedir_perm}" | cut -d" " -f1 | grep -c "x")
  if (( exec_perms_count < 3 )); then
    status_msg "授予NGINX所需的权限 ..."
    chmod og+x "${home}/home/print3D" && ok_msg "Done!"
  fi
  return
}
function symlink_webui_nginx_log() {
  local interface path access_log error_log regex logpaths
  interface=${1}
  access_log="/var/log/nginx/${interface}-access.log"
  error_log="/var/log/nginx/${interface}-error.log"
  path="${DATABK}/log"
    [[ ! -d ${path} ]] && mkdir -p "${path}"
    if [[ -f ${access_log} && ! -L "${path}/${interface}-access.log" ]]; then
      status_msg "正在为 ${access_log}创建链接 ..."
      ln -s "${access_log}" "${path}"
      ok_msg "Symlink已创建: ${path}/${interface}-access.log"
    fi
    if [[ -f ${error_log} && ! -L "${path}/${interface}-error.log" ]]; then
      status_msg "正在为  ${error_log}创建链接 ..."
      ln -s "${error_log}" "${path}"
      ok_msg "Symlink已创建: ${path}/${interface}-error.log"
    fi

}
function download_fluidd_macros() {
  local path=${DATABK}/config
  status_msg "克隆fluidd配置 ..."
  wget ${FLUIDD_MACRO} -P "${path}";
  #patch_fluidd_update_manager
  ok_msg "Done!"
}
function patch_fluidd_update_manager() {
 local fluidd_cfg path line gcode_dir conf
 path=${DATABK}/config 
 conf="${DATABK}/config/moonraker.conf"
    if ! grep -Eq "^\[include fluidd.cfg\]$" "${path}/printer.cfg"; then
       log_info "${path}/printer.cfg"
       sed -i "1 i [include fluidd.cfg]" "${path}/printer.cfg"
       sed -i "/serial:/c serial: /dev/ttyOcto4a \n \#baud: 115200 \#\(非必须，默认波特率连不上可改为115200\) " "${path}/printer.cfg"
    fi
    line="$(($(grep -n "\[include fluidd.cfg\]" "${path}/printer.cfg" | tail -1 | cut -d: -f1) + 1))"
    gcode_dir="${DATABK}/gcodes"
    if ! grep -Eq "^\[virtual_sdcard\]$" "${path}/fluidd.cfg"; then
       log_info "${path}/fluidd.cfg"
       sed -i "${line} i \[virtual_sdcard]\n path: ${gcode_dir}\n on_error_gcode: CANCEL_PRINT\n" "${path}/fluidd.cfg"
    fi

    if ! grep -Eq "^\[update_manager fluidd\]\s*$" "${conf}"; then
      ### add new line to conf if it doesn't end with one
      [[ $(tail -c1 "${conf}" | wc -l) -eq 0 ]] && echo "" >> "${conf}"
      ### add Fluidds update manager section to moonraker.conf
      status_msg "将Fluidd添加到文件中的更新管理器:\n ${conf}"
      /bin/sh -c "cat >> ${conf}" << MOONRAKER_CONF

[update_manager fluidd]
type: web
channel: stable
repo: fluidd-core/fluidd
path: /home/print3D/fluidd
MOONRAKER_CONF

    fi
}
function install_script_nginx(){
    
    chmod +x /etc/init.d/nginxk
    chmod 777 /etc/init.d/nginxk
}
#===================================================#
#================= INSTALL MAINSAIL ================#
#===================================================#
function install_mainsail() {
  status_msg "正在初始化mainsail安装 ..."
  download_mainsail
  set_nginx_cfg "mainsail"
  symlink_webui_nginx_log "mainsail"
  download_mainsail_macros
  install_script_nginx
  print_confirm "mainsail已设置!"
}
function download_mainsail() {
  local url
  url=$(get_mainsail_download_url)
  status_msg "正在从 ${url} ..."
  if [[ -d ${MAINSAIL_DIR} ]]; then
    rm -rf "${MAINSAIL_DIR}"
  fi
  mkdir "${MAINSAIL_DIR}" && cd "${MAINSAIL_DIR}"

  if wget "${url}"; then
    ok_msg "下载完成!"
    status_msg "Extracting archive ..."
    unzip -q -o ./*.zip && ok_msg "Done!"
    status_msg "正在提取存档 ..."
    rm -rf ./*.zip && ok_msg "Done!"
  else
    print_error "正在从\n ${url}\n 失败!"
    
  fi
}
function get_mainsail_download_url() {
  local ms_tags tags latest_tag latest_url stable_tag stable_url url
  tags=$(curl -s "${MAINSAIL_TAGS}" | grep "name" | cut -d'"' -f4)
  download_url=$(curl -s "${MAINSAIL_TAGS}" | grep "download_url" | cut -d'"' -f4)
  # 获取最新标签和url
  latest_tag=$(echo "${tags}" | head -1)
  latest_url=$(echo "${download_url}" | head -1)
  url="${latest_url}"
  echo "${url}"
}
function download_mainsail_macros() {
  local path="${DATABK}/config"
  status_msg "克隆 mainsail配置 ..."
  wget ${MAINSAIL_MACRO} -P "${path}";
  #patch_mainsail_update_manager
  ok_msg "Done!"
}
function patch_mainsail_update_manager() {
  local ms_cfg_repo path  line gcode_dir conf
  path="${DATABK}/config"
  conf="${DATABK}/config/moonraker.conf"
  if ! grep -Eq "^\[include mainsail.cfg\]$" "${path}/printer.cfg"; then
    log_info "${path}/printer.cfg"
    sed -i "1 i [include mainsail.cfg]" "${path}/printer.cfg"
  fi
  line="$(($(grep -n "\[include mainsail.cfg\]" "${path}/printer.cfg" | tail -1 | cut -d: -f1) + 1))"
  gcode_dir="${DATABK}/gcodes"
  if ! grep -Eq "^\[virtual_sdcard\]$" "${path}/mainsail.cfg"; then
      log_info "${path}/mainsail.cfg"
      sed -i "${line} i \[virtual_sdcard]\n path: ${gcode_dir}\n on_error_gcode: CANCEL_PRINT\n" "${path}/mainsail.cfg"
  fi
  if ! grep -Eq "^\[update_manager mainsail\]\s*$" "${conf}"; then
    ### add new line to conf if it doesn't end with one
    [[ $(tail -c1 "${conf}" | wc -l) -eq 0 ]] && echo "" >> "${conf}"
    ### add Mainsails update manager section to moonraker.conf
    status_msg "将Mainsail添加到文件中的更新管理器:\n       ${conf}"
    /bin/sh -c "cat >> ${conf}" << MOONRAKER_CONF

[update_manager mainsail]
type: web
channel: stable
repo: mainsail-crew/mainsail
path: /home/print3D/mainsail
MOONRAKER_CONF
    fi
}

#================================================#
#============= MESSAGE FORMATTING ===============#
#================================================#
function do_action_service() {
  local services action=${1} service=${2}
  services=$(find "${SYSTEMD}" -maxdepth 1 -regextype posix-extended -regex "${SYSTEMD}/${service}(-[0-9a-zA-Z]+)?.service" | sort)

  if [[ -n ${services} ]]; then
    for service in ${services}; do
      service=$(echo "${service}" | rev | cut -d"/" -f1 | rev)
      status_msg "${action^} ${service} ..."

      if sudo systemctl "${action}" "${service}"; then
        log_info "${service}: ${action} > 成功"
        ok_msg "${action^} ${service} 成功!"
      else
        log_warning "${service}: ${action} > 失败"
        warn_msg "${action^} ${service} 失败!"
      fi
    done
  fi
}
function create_virtualenv() {
  local ljm="${1}"
  local wjm="${2}"
  status_msg "正在安装$（“python3”-V）虚拟环境..."
  [[ -d ${ljm} ]] && rm -rf "${ljm}"
  if virtualenv -p "python3" "${ljm}"; then
    "${ljm}"/bin/pip install -U pip  setuptools -i "${PIP3YUAN}"
    "${ljm}"/bin/pip install -r "${wjm}" -i "${PIP3YUAN}"
  else
    sleep 2s
    sudo dpkg --configure -a
    if virtualenv -p "python3" "${ljm}"; then
        "${ljm}"/bin/pip install -U pip  setuptools -i "${PIP3YUAN}"
        "${ljm}"/bin/pip install -r "${wjm}" -i "${PIP3YUAN}"
    else
        log_error "创建python3环境时失败"
        error_msg "virtualenv创建失败！"
    fi
  fi
}
function dependency_check(){
  local dep=( "${@}" )
  local packages
  status_msg "正在检查以下依赖项:"

  #检查是否安装了程序包，如果没有，请将其名称写入数组
  for pkg in "${dep[@]}"; do
    echo -e "${cyan}● ${pkg} ${white}"
    [[ ! $(dpkg-query -f'${Status}' --show "${pkg}" 2>/dev/null) = *\ installed ]] && \
    packages+=("${pkg}")
  done

  #如果数组不为空，则从数组安装程序包
  if (( ${#packages[@]} > 0 )); then
    status_msg "安装以下依赖项:"
    for package in "${packages[@]}"; do
      echo -e "${cyan}● ${package} ${white}"
    done
    echo

    if sudo apt-get update --allow-releaseinfo-change && sudo apt-get install "${packages[@]}" -y; then
      ok_msg "已安装依赖项!"
    else
      error_msg "安装依赖项失败!"
      return 1 # exit kiauh
    fi
  else
    ok_msg "已满足依赖项!"
    return
  fi
}

function select_msg() {
  echo -e "${white}   [➔] ${1}"
}
function status_msg() {
  echo -e "\n${magenta}###### ${1}${white}"
}
function ok_msg() {
  echo -e "${green}[✓ OK] ${1}${white}"
}
function warn_msg() {
  echo -e "${yellow}>>>>>>> ${1}${white}"
}
function error_msg() {
  echo -e "${red}>>>>>>> ${1}${white}"
}
function abort_msg() {
  echo -e "${red}<<<<<<< ${1}${white}"
}
function title_msg() {
  echo -e "${cyan}${1}${white}"
}
function print_error() {
  [[ -z ${1} ]] && return

  echo -e "${red}"
  echo -e "#=======================================================#"
  echo -e " ${1} "
  echo -e "#=======================================================#"
  echo -e "${white}"
}
function print_confirm() {
  [[ -z ${1} ]] && return

  echo -e "${green}"
  echo -e "#=======================================================#"
  echo -e " ${1} "
  echo -e "#=======================================================#"
  echo -e "${white}"
}
function log_info() {
  local message="${1}" log="${LOGFILE}"
  echo -e "$(timestamp) [INFO]: ${message}" | tr -s " " >> "${log}"
}
function log_warning() {
  local message="${1}" log="${LOGFILE}"
  echo -e "$(timestamp) [WARN]: ${message}" | tr -s " " >> "${log}"
}
function log_error() {
  local message="${1}" log="${LOGFILE}"
  echo -e "$(timestamp) [ERR]: ${message}" | tr -s " " >> "${log}"
}
function timestamp() {
  date +"[%F %T]"
}
function report_status(){
    echo -e "\n\n###### $1"
}

status_msg "安装fluidd！"
install_fluidd
status_msg "安装mainsail！"
install_mainsail

exit 0